package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import util.HibernateUtil;
import view.AddBookPage;
import view.EditBookPage;
import bean.Book;
import bean.Catalog;
import bean.Loan;
import dto.BookDTO;
import dto.UserLoanBookDTO;

public class CommonBookController {

	class GetISBNInfoListener implements ActionListener {

		private AddBookPage addBook;
		private EditBookPage editBook;
		private BookDTO dto;
		private String addOrEdit;

		GetISBNInfoListener(AddBookPage addBook) {
			this.addBook = addBook;
			this.addOrEdit = "ADD";
		}

		GetISBNInfoListener(EditBookPage editBook) {
			this.editBook = editBook;
			this.addOrEdit = "EDIT";
		}

		public void actionPerformed(ActionEvent arg0) {
			if (addOrEdit == "ADD") {
				dto = addBook.getBookDTO();
				addBook.displayMessage("         ");
			} else if (addOrEdit == "EDIT") {
				dto = editBook.getBookDTO();
				editBook.displayMessage("         ");
			}

			String ISBN = dto.getISBN();

			if (ISBN == null) {
				if (addOrEdit == "ADD")
					addBook.displayMessage("ISBN field should not be empty.");
				else if (addOrEdit == "EDIT")
					editBook.displayMessage("ISBN field should not be empty.");

			} else {
				Book book = fetchBookByISBN(ISBN);

				// no ISBN exists
				if (book != null) {

					try {
						BeanUtils.copyProperties(dto, book);

					} catch (IllegalAccessException iae) {
						iae.printStackTrace();
					} catch (InvocationTargetException ite) {
						ite.printStackTrace();
					}

					if (addOrEdit == "ADD") {
						addBook.setBookDTO(dto);
						addBook.updateWindowData();
					} else if (addOrEdit == "EDIT") {
						editBook.setBookDTO(dto);
						editBook.updateWindowData();
					}
				} else {
					if (addOrEdit == "ADD")
						addBook.displayMessage("No ISBN in record.");
					else if (addOrEdit == "EDIT")
						editBook.displayMessage("No ISBN in record.");
				}
			}
		}
	}

	Catalog fetchCatalogByDDC(String ddc) {
		Catalog catalogBean = null;

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();

		Query query = session
				.createQuery("SELECT c FROM Catalog c LEFT JOIN FETCH c.book WHERE c.deweyDecimalNo = '"
						+ ddc + "'");

		if (!query.list().isEmpty()) {
			catalogBean = (Catalog) query.list().get(0);
		}

		return catalogBean;
	}

	Book fetchBookByISBN(String ISBN) {

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();

		Query query = session.createQuery(" FROM Book WHERE ISBN = '" + ISBN
				+ "'");

		Book book = null;
		if (!query.list().isEmpty()) {
			book = (Book) query.list().get(0);
		}

		return book;
	}

	List<Loan> fetchLoanByUser(String userId) {
		List<Loan> searchResult = new ArrayList<Loan>();

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();

		Query query = session
				.createQuery("SELECT loan FROM Loan loan LEFT JOIN FETCH loan.catalog WHERE loan.isReturned = 'N' AND loan.userId = '"
						+ userId + "'");

		List loanList = query.list();
		if (!loanList.isEmpty()) {
			for (int i = 0; i < loanList.size(); i++) {
				Loan loan = (Loan) loanList.get(i);
				searchResult.add(loan);
			}
		}

		return searchResult;
	}

	List<UserLoanBookDTO> populateUserLoanBookDTO(List<Loan> searchResult) {

		List<UserLoanBookDTO> userLoanList = new ArrayList<UserLoanBookDTO>();

		for (Loan loan : searchResult) {
			Catalog catalog = loan.getCatalog();
			catalog = fetchCatalogByDDC(catalog.getDeweyDecimalNo());

			UserLoanBookDTO userLoanBookDTO = new UserLoanBookDTO();
			BookDTO bookDTO = new BookDTO();

			try {
				BeanUtils.copyProperties(bookDTO, catalog.getBook());
				bookDTO.setDeweyDecimalNo(catalog.getDeweyDecimalNo());
				bookDTO.setOnLoan(catalog.getOnLoan());
				bookDTO.setRemarks(catalog.getRemarks());

				userLoanBookDTO.setBookDTO(bookDTO);
				userLoanBookDTO.setLoanDate(loan.getLoanDate());
				userLoanBookDTO.setDueDate(loan.getDueDate());

			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}

			userLoanList.add(userLoanBookDTO);
		}

		return userLoanList;
	}

	BookDTO populateBookDTO(String ddc) {
		BookDTO bookDTO = null;

		Catalog catalogBean = fetchCatalogByDDC(ddc);

		if (catalogBean != null) {
			Book bookBean = catalogBean.getBook();
			bookDTO = new BookDTO();

			try {
				BeanUtils.copyProperties(bookDTO, bookBean);
				bookDTO.setDeweyDecimalNo(catalogBean.getDeweyDecimalNo());
				bookDTO.setOnLoan(catalogBean.getOnLoan());
				bookDTO.setRemarks(catalogBean.getRemarks());

			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (InvocationTargetException e1) {
				e1.printStackTrace();
			}
		}

		return bookDTO;
	}

}
